
package com.loooooo.pm2024;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.naming.NameCoder;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDomDriver;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.unit.DataSize;
import org.springframework.web.client.RestTemplate;

import javax.servlet.MultipartConfigElement;
import javax.sql.DataSource;
import java.io.Writer;
import java.lang.instrument.Instrumentation;

@SpringBootApplication
@EnableCaching
//@ComponentScan("net.haoxueba.xpricing")
public class MyApplication implements ApplicationContextAware {
    private static Instrumentation instrumentation;

    public static void premain(String args, Instrumentation inst) {
        instrumentation = inst;
    }

    public static void main(String[] args) {
        //System.setProperty("java.vm.name", "Java HotSpot(TM)");
        //System.out.println(ObjectSizeCalculator.getObjectSize(3L));
//        for (String name : System.getProperties().stringPropertyNames()) {
//            System.out.println(String.format("%s=%s", name, System.getProperties().getProperty(name)));
//        }
        SpringApplication.run(MyApplication.class, args);
    }

    public static Instrumentation getInstrumentation() {
        return instrumentation;
    }

    public static void setInstrumentation(Instrumentation instrumentation) {
        MyApplication.instrumentation = instrumentation;
    }


    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //文件最大
        // org.springframework.util.unit.DataSize
        factory.setMaxFileSize(DataSize.ofMegabytes(200));
        /// 设置总上传数据总大小
        factory.setMaxRequestSize(DataSize.ofMegabytes(200));
        return factory.createMultipartConfig();
    }

    @Autowired
    DataSource dataSource;

    @Bean
    public TransactionTemplate transactionTemplate() {
        PlatformTransactionManager txManager = new DataSourceTransactionManager(dataSource);
        return new TransactionTemplate(txManager);
    }

    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static <T> T getBean(Class<T> clazz) throws BeansException {
        return context.getBean(clazz);
    }

    public static <T> T getBean(String name, Class<T> clazz) throws BeansException {
        return context.getBean(name, clazz);
    }

    public static String getProperty(String name, String defaultValue) {

        return context.getEnvironment().getProperty(name, defaultValue);
    }

    public static String getProperty(String name) {
        return context.getEnvironment().getProperty(name);
    }

    public static <T> T getProperty(String name, Class<T> clazz, T defaultValue) {
        return context.getEnvironment().getProperty(name, clazz, defaultValue);
    }

    public static <T> T getProperty(String name, Class<T> clazz) {
        return context.getEnvironment().getProperty(name, clazz);
    }

    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    static final String CDATA1 = "<![CDATA[";
    static final String CDATA2 = "]]>";

    @Bean
    XStream xStream() {
        final NameCoder nameCoder = new NoNameCoder();
        XStream xStream = new XStream(new XppDomDriver(nameCoder) {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new PrettyPrintWriter(out, nameCoder) {
                    protected void writeText(QuickWriter writer, String text) {
                        if (text.startsWith(CDATA1) && text.endsWith(CDATA2)) {
                            //System.out.println(text);
                            //System.out.println(StringEscapeUtils.unescapeHtml4(text));
                            writer.write(StringEscapeUtils.unescapeHtml4(text));
                        } else super.writeText(writer, text);
                    }
                };
            }

        });
        return xStream;
    }



}
